package LeetCode1;

import java.util.LinkedList;
import java.util.Queue;

//二叉树最大宽度
public class Num662 {
    //该题最主要在于对树节点的二次包装，给每个节点赋予序号，从1开始，其子节点序号分别为2k，2k+1。
    //每层的宽度就等于最左节点与最右节点的差
    public int widthOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //存储对比下来层里的最大宽度
        int maxWidth = 0;
        Queue<NodeWithNum> queue = new LinkedList<>();
        queue.offer(new NodeWithNum(root, 1));
        while (!queue.isEmpty()) {
            //该层节点宽度
            int levelWidth = 0;
            //该层最左节点的序号
            int L = 0;
            //该层最右节点的序号
            int R = 0;
            //该层节点个数
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                NodeWithNum cur = queue.poll();
                if (i == 0) {
                    L = cur.num;
                }
                if (i == size - 1) {
                    R = cur.num;
                }
                if (cur.node.left != null) {
                    queue.offer(new NodeWithNum(cur.node.left, cur.num * 2));
                }
                if (cur.node.right != null) {
                    queue.offer(new NodeWithNum(cur.node.right, cur.num * 2 + 1));
                }
            }
            levelWidth = R - L + 1;
            maxWidth = Math.max(levelWidth, maxWidth);
        }
        return maxWidth;
    }

    public class NodeWithNum {
        //具体二叉树节点
        TreeNode node;
        //给二叉树节点赋予编号
        int num;

        public NodeWithNum(TreeNode node, int num) {
            this.node = node;
            this.num = num;
        }
    }
}
